#ifndef __EVENTLOOP_H__
#define __EVENTLOOP_H__
// #include <muduo/base/CurrentThread.h>
#include "CurrentThread.h"
#include "NonCopyable.h"
#include "TimerQueue.h"

#include <iostream>
#include <atomic>
#include <vector>
#include <memory>
#include <functional>
#include <mutex>

using std::cout;
using std::vector;
using std::unique_ptr;
using std::function;
using std::mutex;

class Channel;
class Poller;

// 每个thread 只能有一个EventLoop对象
class EventLoop : NonCopyable //禁止复制
{
public:
    typedef function<void()> TimerCallback;
    typedef function<void()> Functor;
    EventLoop(); // 检查线程是否创建了其他EventLoop对象
    ~EventLoop();

    void loop();

    bool isInLoopThread() const { return _threadId == CurrentThread::tid(); }
    void assertInLoopThread()
    {
        if(!isInLoopThread())
        {
            abortNotInLoopThread();
        }
    }

    static EventLoop *getEventLoopOfCurrentThread(); // 获取当前线程的EventLoop对象

    void quit();

    void updateChannel(Channel *channel);
    void removeChannel(Channel *channel); //从Poller中删除channel
    void wakeup(); //唤醒IO线程

    TimerId runAt(Timestamp time, TimerCallback cb);
    TimerId runAfter(double delay, TimerCallback cb);
    TimerId runEvery(double interval, TimerCallback cb);

    void runInLoop(Functor cb); //执行回调 if当前IO线程执行 then回调会同步进行
    void queueInLoop(Functor cb); //在其他IO线程执行回调 先入队列 再唤醒这个IO线程
private:
    void abortNotInLoopThread();
    void handleRead(); 
    void doPendingFunctors();

    typedef vector<Channel *> ChannelList;

    std::atomic_bool _isLooping;
    std::atomic_bool _quit;
    std::atomic_bool _callingPendingFunctors;

    const pid_t _threadId; // 所属线程id (IO线程)
    Timestamp _pollReturnTime;
    unique_ptr<Poller> _poller;
    unique_ptr<TimerQueue> _timerQueue;
    int _wakeupFd; // 唤醒IO线程eventfd
    unique_ptr<Channel> _wakeupChannel;
    ChannelList _activeChannels;

    mutex _mutex;
    vector<Functor> _pendingFunctors;  //互斥队列 暴露给其他线程
};

#endif